import {
  createStore,
  Plugin,
  PluginFunctions,
  RenderViewer,
  Slot,
} from "../../core";

import ScrollMode from "./ScrollMode";
import StoreProps from "./StoreProps";
import SwitchScrollMode, { SwitchScrollModeProps } from "./SwitchScrollMode";
import SwitchScrollModeButton from "./SwitchScrollModeButton";
import SwitchScrollModeMenuItem from "./SwitchScrollModeMenuItem";
import Tracker from "./Tracker";
import { ReactElement, useMemo } from "react";

export interface SwitchScrollModeButtonProps {
  mode: ScrollMode;
}

export interface SwitchScrollModeMenuItemProps {
  mode: ScrollMode;
  onClick(): void;
}

interface ScrollModePlugin extends Plugin {
  SwitchScrollMode(props: SwitchScrollModeProps): ReactElement;
  SwitchScrollModeButton(props: SwitchScrollModeButtonProps): ReactElement;
  SwitchScrollModeMenuItem(props: SwitchScrollModeMenuItemProps): ReactElement;
}

export interface ScrollModePluginProps {
  scrollMode?: ScrollMode;
}

const scrollModePlugin = (props?: ScrollModePluginProps): ScrollModePlugin => {
  const store = useMemo(
    () =>
      createStore<StoreProps>({
        scrollMode:
          props && props.scrollMode ? props.scrollMode : ScrollMode.Vertical,
      }),
    []
  );

  const SwitchScrollModeDecorator = (props: SwitchScrollModeProps) => (
    <SwitchScrollMode {...props} store={store} />
  );

  const SwitchScrollModeButtonDecorator = (
    props: SwitchScrollModeButtonProps
  ) => (
    <SwitchScrollModeDecorator mode={props.mode}>
      {(p) => (
        <SwitchScrollModeButton
          isSelected={p.isSelected}
          mode={p.mode}
          onClick={() => {
            p.onClick();
          }}
        />
      )}
    </SwitchScrollModeDecorator>
  );

  const SwitchScrollModeMenuItemDecorator = (
    props: SwitchScrollModeMenuItemProps
  ) => (
    <SwitchScrollModeDecorator mode={props.mode}>
      {(p) => (
        <SwitchScrollModeMenuItem
          isSelected={p.isSelected}
          mode={p.mode}
          onClick={() => {
            p.onClick();
            props.onClick();
          }}
        />
      )}
    </SwitchScrollModeDecorator>
  );

  const renderViewer = (props: RenderViewer): Slot => {
    const currentSlot = props.slot;
    if (currentSlot && currentSlot.children) {
      currentSlot.children = (
        <>
          <Tracker store={store} />
          {currentSlot.children}
        </>
      );
    }

    return currentSlot;
  };

  return {
    install: (pluginFunctions: PluginFunctions) => {
      store.update("getPagesContainer", pluginFunctions.getPagesContainer);
    },
    renderViewer,
    SwitchScrollMode: SwitchScrollModeDecorator,
    SwitchScrollModeButton: SwitchScrollModeButtonDecorator,
    SwitchScrollModeMenuItem: SwitchScrollModeMenuItemDecorator,
  };
};

export default scrollModePlugin;
